<template>
  <div class="modelView">
<!--    modelListInit: [],-->
<!--    modelList: [],-->
<!--    handleLeftBox: {-->
<!--    flag: true,-->
<!--    isIndeterminate: false,-->
<!--    allMmodel: false,-->
<!--    choseModels: [],-->
<!--    },-->
    <vHeader 
    licon="el-amsp-zuzhi2"
    @lclick="handleLeftBox.flag=!handleLeftBox.flag"/>
    <vLeft v-show="handleLeftBox.flag" 
    :handleLeftBox="handleLeftBox"
    :modelList="modelList"
    :areaVolume="three.areaVolume"
    @changeShow="changeShow"/>
    <!-- @getMInfo="getMInfo" -->

    <div class="vsBox" v-show="vsBoxData.volume">
        <p><span>体积 (mm³):</span>
           {{vsBoxData.volume.toFixed(2)}} 
        </p>
        <p><span>表面积 (mm²):</span>
           {{vsBoxData.area.toFixed(2)}} 
        </p>
        <p><span>体积占比(%):</span>
          {{(vsBoxData.volume/totalVolume * 100 || 0).toFixed(2)+ '%'}}
        </p>
        <p><span>最小包围盒 (mm):</span>
           {{vsBoxData.boxsize.x.toFixed(2)}}×{{vsBoxData.boxsize.y.toFixed(2)}}×{{vsBoxData.boxsize.z.toFixed(2)}}
        </p>
    </div>

    <vBottomTwo :handleBottomBox="handleBottomBox" :handleBottomBtn="handleBottomBtn"
    @toolFn="toolFn" @sixView="sixView"/>

    <vBottom :handleBottomBox="handleBottomBox" :handleLeftBox="handleLeftBox"/>

    <amsp-pop class="addLinePop" title="标注" width="80%" :visible.sync="commentBox.newLine.flag" :before-close="clearLine">
      <el-form class="addLineForm" ref="addLineForm" :model="commentBox.newLine.form" :rules="commentBox.newLine.rules"  label-position="left" label-width="90px" @submit.native.prevent>
            <el-form-item label="标注人" prop="user">
              <el-input placeholder="请输入标注人" v-model.trim="commentBox.newLine.form.user" disabled @blur="onBlur"></el-input>
            </el-form-item>
            <el-form-item label="标注内容" prop="content">
              <el-input placeholder="请输入标注内容" v-model.trim="commentBox.newLine.form.content" @blur="onBlur"></el-input>
            </el-form-item>
          <div class="addLineeFormBtns">
            <el-button round @click="clearLine">取消</el-button>
            <el-button round type="primary" @click="setAddLinePop">确定</el-button>
          </div>

      </el-form>
    </amsp-pop>

    <!-- <amsp-pop class="addLinePop" title="标记" width="90%" :visible.sync="handleBottomBtn.mark" :before-close="() => {handleBottomBtn.mark=false}">
    </amsp-pop> -->
      <!-- <vMark ref="vMark" v-if="handleBottomBtn.mark"/> -->
    <div class="screen3d" ref="screen3d" v-loading="three.loading" :element-loading-text="loadText"></div>
    <div id="inset3d"></div>
  </div>
</template>

<script>
import Vue from 'vue'
import * as THREE from 'three';
import { ThreeMFLoader } from 'three/examples/jsm/loaders/3MFLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// import { TransformControls } from 'three/examples/jsm/controls/TransformControls.js';
import { CSS2DRenderer, CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
// import { VertexNormalsHelper } from 'three/examples/jsm/helpers/VertexNormalsHelper.js';



  // import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';
  // import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
  // import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
  // import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js';
  // import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js';

import html2canvas from "html2canvas"

import {deepCopy} from '@/utils/tools/tools'

import {addLabelContent, queryLabelContents} from '@/depends/api/labelContent'
import {uploadModelColorBase64} from '@/depends/api/medicalRecord'


import vHeader from './pub/v-header'
import vLeft from './modelView/v-left'
import vBottom from './modelView/v-bottom'
import vBottomTwo from './modelView/v-bottom-two'
// import vMark from './modelView/v-mark'
import newApp from './modelView/newApp'
import {mapGetters} from "vuex";
// let currentDownUp = {
//   time: 0,
//   downKey: ''
// };




let moved = false;

let threeObj2 = {
  container2: null,
  renderer2: null,
  camera2: null,
  axes2: null,
  scene2: null
}
let threeObj = {

  // composer: null,
  // outlinePass: null,
  // effectFXAA: null,


  currentKey: '',
  renderer: null,
  controls: null,
  manager: null,
  // transformControl: null,
  centerModel: null,
  scene: null,
  labelRenderer: null,
  models: {},
  modelsMeshs: [],
  modelsHelper: {},
  group: null,
  modelsClipPlanes: {},
  mouse: null,
  raycaster: null,
  content: {
    ambientLight: null,
    directionalLight: null,
    grid: null,
  },
  loder: {
    ThreeMFLoader: null,
  }
}
let onPointerUpsTime = ''
export default {
  components: {
    vHeader,
    vLeft,
    vBottom,
    vBottomTwo,
    // vMark
  },
  props: ['modelLists'],
  // provide () {
  //   return {
  //     handleLeftBox: this.handleLeftBox
  //   }
  // },
  data() {
    return {
      vsBoxData: {
        volume: 0,
        area: 0,
        num:0,
        boxsize: {x: 0, y: 0, z: 0}
      },
      totalVolume: 0,
      modelListInit: [],
      modelList: [],
      handleLeftBox: {
        flag: true,
        isIndeterminate: false,
        allMmodel: false,
        choseModels: [],
      },
      handleBottomBtn: {
        annotation: false,
        measureLong: false,
        measureAngle: false,
        activeSixViewIndex:0,
        annotationArr: [],
        measureLongArr: [],
        measureAngleArr: [],
        hiddenMeasure: false
      },
      pointLocation: {
        line: [],
        lineMesh: [],
        overType: [],
      },
      commentBox: {
        comments: [],
        newLine: {
          flag: false,
          form: {
            id: '',
            user: '',
            content: ''
          },
          rules: {
            user: [{ required: true, message: '请输入标注人', trigger: 'blur' }],
            content: [{ required: true, message: '请输入标注内容', trigger: 'blur' }],
          }
        }
      },
      handleBottomBox: {
        tool: {
          flag: false,
        },
        sixView: {
          flag: false
        },
        sectionFrom: {
          flag: false,
          xRange: [0,0],
          yRange: [0,0],
          zRange: [0,0],
          x: [],
          y: [],
          z: []
        },
        colorFrom: {
          flag: false,
          colors: ['#fff0ce','#ff0000','#0055ff','#642b1a','#75534a','#aaaaff','#00ffff','#55ff00','#55ff7f','#aaff7f','#ffaaff','#ffffff','#dfdfdf','#ffaa00','#55aaff','#fad8cc','#c01212','#ffff00'],
          color: ''
        },
        alphaFrom: {
          flag: false,
          opacity: 100
        },
      },
      three: {
        loading: false,
        loadProgress: {

        },
        areaVolume: {area: 0, volume: 0}
      },
      sessionId:'',
      userInfo:{
        sessionId:'',
        name:''
      },
      newBoxFlag:false
    };
  },
  computed:{
    ...mapGetters('user', ['getUserInfo']),
    loadText () {
      let _new = {
        cur: 0,
        total: 0
      }
      for (let a in this.three.loadProgress) {
        _new.cur += Number(this.three.loadProgress[a])
        _new.total += Number(a)
      }
      return '平台未开小差,请耐心等待 '+ ((_new.cur / _new.total * 100)  || 0).toFixed(2) + '%'
    }
    
  },
  created() {
    this.modelList = this.modelLists
    this.modelListInit = deepCopy(this.modelList)
    this.handleLeftBox.choseModels = []
    this.userInfo = this.getUserInfo;
    if(typeof this.userInfo.sessionId !=='undefined'){
      this.commentBox.newLine.form.user = this.userInfo.name;
    }else{
      this.commentBox.newLine.form.user='';
    }

  },
  mounted() {
    this.init()
    this.animate()
    if(typeof this.userInfo.sessionId !=='undefined'){ //sessionId 存在 进行ws连接
      this.queryLabelContents()
      this.wsinit();
    }else{
      this.commentBox.comments = this.commentBox.comments.filter(a => {
        a.lineMesh[1].remove(a.lineMesh[1].children[0])
        threeObj.scene.remove(a.lineMesh[0])
        threeObj.scene.remove(a.lineMesh[1])
        threeObj.scene.remove(a.lineMesh[2])
      })

    }

  },
  methods:{
     //获取所有模型总体积
     getTotalVolume () {
      this.totalVolume = 0;
      this.modelList.forEach((mode, b) => {
        let modeInfo = this.getAreaVolume(threeObj.models[`${mode.id}meshs`])
        this.totalVolume += Number(modeInfo.volume)
      })
      console.log(this.totalVolume)
    },
    getMInfo (modes) {
      this.vsBoxData = {
        volume: 0,
        area: 0,
        num:0,
        boxsize: {x: 0, y: 0, z: 0}
      }
      if (!this.handleLeftBox.choseModels.length) {
        return
      }
      modes.forEach((mode, b) => {
        if (this.handleLeftBox.choseModels.includes(b) && !mode.volume) {
          let modeInfo = this.getAreaVolume(threeObj.models[`${mode.id}meshs`])
          mode.volume = modeInfo.volume
          mode.area = modeInfo.area
          mode.boxsize = modeInfo.boxsize
        }
      })
      let g = new THREE.Group()
      this.handleLeftBox.choseModels.forEach(a => {
        this.vsBoxData.volume += Number(modes[a].volume)
        this.vsBoxData.area += Number(modes[a].area)
        g.add(threeObj.models[a].clone())
      })
      this.vsBoxData.boxsize = (new THREE.Box3().setFromObject(g)).getSize()
    },
    getAreaVolume (mode) {
      let meshArr = [...mode]
        //let geometry = new THREE.Geometry();
        let geometry = new THREE.BufferGeometry();
      let area = 0;
      let volume = 0;

      function areaOfTriangle (p1, p2, p3) {
        let v1 = new THREE.Vector3();
        let v2 = new THREE.Vector3();
        let v3 = new THREE.Vector3();
        v1 = p1.clone().sub(p2);
        v2 = p1.clone().sub(p3);

        v3.crossVectors(v1,v2);
        let s = v3.length()/2;
        return s
      }
      function volumeOfTriangle(p1, p2, p3) {
        return p1.clone().cross(p2).dot(p3) / 6;
      }
      function getSize () {
        let g = new THREE.Group()
        meshArr.forEach(a => {
          g.add(a.clone())
        })
        let s = (new THREE.Box3().setFromObject(g)).getSize()
        return s
      }
      meshArr.forEach(mesh => {
        let geometryArray = mesh.geometry.attributes.position.array
        for (let a = 0; a < geometryArray.length; a+=9) {
          let triangle = [
                    new THREE.Vector3(geometryArray[a], geometryArray[a+1], geometryArray[a+2]),
                    new THREE.Vector3(geometryArray[a+3], geometryArray[a+4], geometryArray[a+5]),
                    new THREE.Vector3(geometryArray[a+6], geometryArray[a+7], geometryArray[a+8])]
          area += areaOfTriangle(...triangle)
          volume += volumeOfTriangle(...triangle)
        }
      })
      

      return {area: area.toFixed(2), volume: volume.toFixed(2), boxsize: getSize(meshArr)}
      // this.three.areaVolume = {area: area.toFixed(2), volume: volume.toFixed(2)}
    },
    isPass(form) {
      if(typeof this.userInfo.sessionId =='undefined'){
        this.$message.error('游客账号不能保存标注信息');
        return;
      }
      return new Promise((reslove, reject) => {
        this.$refs[form].validate((valid) => {
          reslove(valid);
        });
      });
    },
    async setAddLinePop () {
      let isPass = await this.isPass('addLineForm');
      if (!isPass) {return}
       let par = {
         medicalRecordId: this.$route.params.id,
         line: JSON.stringify(this.pointLocation.line),
         contents: [this.commentBox.newLine.form]
       }
       if (this.commentBox.newLine.form.id) {
         par.id = this.commentBox.newLine.form.id
       }
      addLabelContent(par).then(res => {
        if (res.data.status != 200) { return }
        this.$message.success('添加成功!')
        if (!par.id) {
          this.commentBox.newLine.form.id = res.data.data
          this.commentBox.comments.push({
            id: res.data.data,
            line: this.pointLocation.line,
            lineMesh: this.pointLocation.lineMesh,
            contents: []
            // contents: [{user: this.commentBox.newLine.form.user, content: this.commentBox.newLine.form.content, }]
          })
        }
        let ws_par = {
          medicalRecordId: this.$route.params.id,
          createBy:this.userInfo.id.toString(),
          name:this.userInfo.name,
          type:1,
          modelLabelId:this.commentBox.newLine.form.id,
          message:this.commentBox.newLine.form.content
          /*line: JSON.stringify(this.pointLocation.line),
          contents: [this.commentBox.newLine.form]*/
        }
        if (this.commentBox.newLine.form.id) {
          ws_par.id = this.commentBox.newLine.form.id
        }
        this.wssend(ws_par);

        // this.pointLocation.lineMesh[3].$children[0].addList(deepCopy(this.commentBox.newLine.form))
        this.pointLocation.line = []
        this.pointLocation.lineMesh = []
        this.clearLine(true)

      })
    },
    queryLabelContents () {
      queryLabelContents({id: this.$route.params.id,}).then(res => {
        if (res.data.status != 200) { return }
        if (!res.data.data) {return}
        this.commentBox.comments = res.data.data.map((a,b) => {
          return this.showLabel(a)
        })
        // console.log('commentBox.comments',this.commentBox.comments);
      })
    },
    showLabel (a) {
      // commentBox.comments
      a.line = JSON.parse(a.line)
      a.lineMesh = []

      a.lineMesh[0] = this.createPoint(a.line[0])
      let sphere1 = a.lineMesh[1] = this.createPoint(a.line[1])
      a.lineMesh[2] = this.createLine(a.line)

      const moonDiv = document.createElement( 'div' );
      moonDiv.className = 'labelBox';
      moonDiv.id = `labelBox-${sphere1.uuid}`

      const nap = document.createElement('div')
      nap.id = 'newApp'
      moonDiv.appendChild(nap)

      const moonLabel = new CSS2DObject( moonDiv );
      sphere1.add( moonLabel );

      // moonDiv.addEventListener('touchend', (event) => {
      //   if (moved) { return }
      //   this.newContent(sphere1.uuid)
      // }, false)
      // moonDiv.addEventListener('click', (event) => {
      //   if (moved) { return }
      //   this.newContent(sphere1.uuid)
      // }, false)
      this.render();

      this.$nextTick(() => {
        let _this = this
        a.lineMesh[3] = new Vue({
          render: h=> h(newApp),
          data(){
            return{
              pthis: _this,
              uuid: sphere1.uuid
            }
          }
        }).$mount(`#${moonDiv.id} #newApp`)

        a.lineMesh[3].$children[0].setList(a.contents)
        this.render();
      })


      return a
    },
    setPlane (x, y, min, v) {
      if (!this.handleLeftBox.choseModels.length) { return }
      this.handleLeftBox.choseModels.forEach(i => {
        threeObj.modelsClipPlanes[i][x].constant = v[1]
        threeObj.modelsClipPlanes[i][y].constant = -v[0]
      })
      this.render();
    },
    setColor (a, b) {
      a = a || this.handleBottomBox.colorFrom.color
      b = b || this.handleLeftBox.choseModels
      if (!b.length) { return }
      this.handleLeftBox.choseModels.forEach(i => {
        threeObj.models[i].traverse(( child ) => {
          // if ( child.material ) console.log(child)
          if ( child.material ) child.material.color.set(a);
          if ( child.geometry ) console.log(child.geometry)
        });
      })
      this.render();
    },
    setAlpha (a,b) {
      a = a || this.handleBottomBox.alphaFrom.opacity
      b = b || this.handleLeftBox.choseModels
      if (!b.length) { return }
      this.handleLeftBox.choseModels.forEach(i => {
        this.modelList.filter(x => x.id == i)[0].show = !(a < 5)
        // this.modelList.map(x => {
        //   if (x.id == i) {
        //     x.
        //   }
        // })
        threeObj.models[i].visible = !(a < 5)
        threeObj.models[i].traverse(( child ) => {
          child.renderOrder=1
           if(child.name.indexOf('肝脏')>-1&&(child.name.indexOf('预留')>-1||child.name.indexOf('预切')>-1)){
            child.renderOrder=2
          }
          if ( child.material ) {
              //透明度为100%
              // console.log(child)
              // console.log(a)
              if(a==100){
                  child.material.transparent = true //是否透明
                  child.material.depthWrite = true
              }else{
                  //透明度为100%以下
                  child.material.transparent = true;
                  // if(child.name.indexOf('肝脏')>-1){
                  //   child.depthWrite=false
                  // }
                    child.material.depthWrite = false;
              }
            child.material.opacity = a/100
          }
        });
      })
      this.render();
    },
    changeShow (a) {
      a.show = !a.show
      threeObj.models[a.id].visible = a.show
      this.render();
    },
    resetThree () {
      threeObj.controls.target.set( 0, 0, 0 );
      threeObj.controls.update();
      this.modelList = deepCopy(this.modelListInit)

      // threeObj.models[a.id].visible = a.show
      this.modelList.map(a => {
        threeObj.models[a.id].visible = a.show
        threeObj.models[a.id].traverse( function ( child ) {
            if (child.type == 'Mesh') {
              // child.visible = a.show
              child.material.color.set(child.material.rcolor.clone())
              child.material.opacity = a.opacity
            }
        })
      })
      // this.reloadDepthWrite();
      this.handleLeftBox.choseModels = []
      this.handleLeftBox.allMmodel = false
      // for (let a in threeObj.modelsHelper) {
      //   threeObj.modelsHelper[a].visible = false
      // }
      this.handleBottomBox.sectionFrom.flag = false
      this.handleBottomBox.colorFrom.flag = false
      this.handleBottomBox.alphaFrom.flag = false
      // this.handleBottomBtn.annotation = false
      
      threeObj.scene.position.set(0,0,0)
      this.resetXYZ()
      this.render();
    },
    init () {
      threeObj.raycaster = new THREE.Raycaster();
      threeObj.mouse = new THREE.Vector2();


      threeObj.renderer = new THREE.WebGLRenderer({ preserveDrawingBuffer: true, antialias: true })
      // threeObj.renderer.setPixelRatio(window.devicePixelRatio);
        //dpr > 2 的机型如：iphone6plus 等，需注意模型太大时，会导致闪退，需要设置
      threeObj.renderer.setPixelRatio(window.devicePixelRatio<3 ? window.devicePixelRatio : 1)
      threeObj.renderer.setSize(window.innerWidth, window.innerHeight);
      this.$refs.screen3d.appendChild(threeObj.renderer.domElement);

      threeObj.labelRenderer = new CSS2DRenderer();
      threeObj.labelRenderer.setSize( window.innerWidth, window.innerHeight );
      threeObj.labelRenderer.domElement.className = 'labelRendererBox'
      threeObj.labelRenderer.domElement.style.position = 'absolute';
      threeObj.labelRenderer.domElement.style.top = '0px';
      threeObj.labelRenderer.domElement.style.zIndex = '1'
      this.$refs.screen3d.appendChild( threeObj.labelRenderer.domElement );


      threeObj.scene = new THREE.Scene();
      threeObj.scene.background = new THREE.Color(0xffffff);
      threeObj.scene.add( new THREE.AmbientLight( 0xffffff, 0.2 ) );
      threeObj.camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 10000);


      threeObj.camera.up.set( 0, 0, 1 );
      threeObj.scene.add( threeObj.camera );



      
      threeObj.group = new THREE.Group()

      threeObj.renderer.clippingPlanes = [];
      threeObj.renderer.localClippingEnabled = true;

      // const controls = new OrbitControls( camera, threeObj.labelRenderer.domElement );

      threeObj.controls = new OrbitControls(threeObj.camera, threeObj.labelRenderer.domElement);
      threeObj.controls.addEventListener( 'change', this.render );
      threeObj.controls.target.set( 0, 0, 0 );
      threeObj.controls.update();

      // threeObj.transformControl = new TransformControls( threeObj.camera, threeObj.labelRenderer.domElement );
      // threeObj.transformControl.enabled = false;
      // threeObj.transformControl.setSize(0.8)
      // threeObj.transformControl.addEventListener( 'change', this.render );
      // // threeObj.transformControl.up.set( 1, 0, 0 )
      // threeObj.scene.add( threeObj.transformControl );

        // const moonDiv = document.createElement( 'div' );
        // const nap = document.createElement('div')
        // nap.id = 'newApp'
        // moonDiv.appendChild(nap)
        // moonDiv.className = 'labelBox';
        // const moonLabel = new CSS2DObject( moonDiv );
        // moonDiv.id = `labelBox-${sphere.uuid}`
        // sphere.add( moonLabel );

        // moonDiv.addEventListener('touchend', (event) => {
        //   if (moved) { return }
        //   this.newContent(event, moonDiv, sphere.uuid)
        // }, false)
        // moonDiv.addEventListener('click', (event) => {
        //   if (moved) { return }
        //   this.newContent(event, moonDiv, sphere.uuid)
        // }, false)
        const _div = document.createElement( 'div' )
        _div.id = '_indicateLabel'
        // const _indicateLabel = new CSS2DObject( _divDiv )
        threeObj.centerModel = new CSS2DObject( _div )
        // threeObj.centerModel.position.set(90,90,90)
        threeObj.centerModel.visible = false
        threeObj.scene.add( threeObj.centerModel );

      // threeObj.centerModel = new THREE.Mesh( new THREE.SphereBufferGeometry( 5, 32, 32 ), new THREE.MeshBasicMaterial( {color: 0x1296DB, 
      //   depthTest : true, depthWrite: true, side: THREE.DoubleSide} ) );
      // threeObj.centerModel.visible = false
      // threeObj.scene.add( threeObj.centerModel );
      


      threeObj.camera.add( new THREE.PointLight( 0xffffff, 0.8 ) );


      threeObj.manager = new THREE.LoadingManager();
      threeObj.manager.onProgress = function ( item, loaded, total ) {
        // console.log( item, loaded, total );
      };

      threeObj.loder.ThreeMFLoader = new ThreeMFLoader(threeObj.manager);
      // console.log(threeObj.loder.ThreeMFLoader)
      threeObj.loder.ThreeMFLoader.requestHeader['Cache-Control'] = 'max-age=30'
      // threeObj.loder.ThreeMFLoader.requestHeader['Pragma'] = 'public'


      this.initModels(this.modelList)



      // threeObj.composer = new EffectComposer( threeObj.renderer );

      // const renderPass = new RenderPass( threeObj.scene, threeObj.camera );
      // threeObj.composer.addPass( renderPass );

      // threeObj.outlinePass = new OutlinePass( new THREE.Vector2( window.innerWidth, window.innerHeight ), threeObj.scene, threeObj.camera );
      // threeObj.composer.addPass( threeObj.outlinePass );
      // threeObj.outlinePass.edgeStrength = 3

      // threeObj.outlinePass.visibleEdgeColor.set( '#ff0000' )
      // threeObj.outlinePass.hiddenEdgeColor.set( '#ffff00' );

      // threeObj.effectFXAA = new ShaderPass( FXAAShader );
      // threeObj.effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );
      // threeObj.composer.addPass( threeObj.effectFXAA );

      this.setupInset();

      window.addEventListener( 'resize', this.onWindowResize );
      // pointerdown
      // pointerup
      threeObj.controls.addEventListener( 'change', () => { moved = true; });
      threeObj.labelRenderer.domElement.addEventListener( 'pointerdown', () => { moved = false; }, false );
      threeObj.labelRenderer.domElement.addEventListener( 'pointerup', this.onPointerUps, false );
      threeObj.labelRenderer.domElement.addEventListener( 'touchstart', () => { moved = false; }, false );
      threeObj.labelRenderer.domElement.addEventListener( 'touchend', this.onPointerUps, false );



    },
    setupInset () {

        const insetWidth = 100, insetHeight = 100;
        threeObj2.container2 = document.getElementById( 'inset3d' );
        threeObj2.container2.width = insetWidth;
        threeObj2.container2.height = insetHeight;

        // renderer
        threeObj2.renderer2 = new THREE.WebGLRenderer( { alpha: true } );
        threeObj2.renderer2.setClearColor( 0x000000, 0 );
        threeObj2.renderer2.setSize( insetWidth, insetHeight );
        threeObj2.container2.appendChild( threeObj2.renderer2.domElement );

        // scene
        threeObj2.scene2 = new THREE.Scene();

        // camera
        threeObj2.camera2 = new THREE.PerspectiveCamera( 50, insetWidth / insetHeight, 1, 1000 );
        threeObj2.camera2.up = threeObj.camera.up; // important!

        // axes
        threeObj2.axes2 = new THREE.AxesHelper( 100 );
        threeObj2.scene2.add( threeObj2.axes2 );
    },
    animate() {

      window.requestAnimationFrame( this.animate );

      threeObj.controls.update();

      //copy position of the camera into inset

      threeObj.renderer.render( threeObj.scene, threeObj.camera );


      threeObj2.camera2.position.copy( threeObj.camera.position );
      threeObj2.camera2.position.sub( threeObj.controls.target );
      threeObj2.camera2.position.setLength( 300 );
      threeObj2.camera2.lookAt( threeObj2.scene2.position );
      threeObj2.renderer2.render( threeObj2.scene2, threeObj2.camera2 );


    },
    createPoint(xyz, color = '0xFF0000') {
      let geometry = new THREE.SphereGeometry( 0.6, 32, 32 );
      let material = new THREE.MeshLambertMaterial( {color: 0xff0000} );
      let sphere = new THREE.Mesh( geometry, material );

      sphere.position.set(...xyz)
      threeObj.scene.add( sphere );
      return sphere
    },
    createLine(vertices, color = '0x00FF00') {
      vertices = new Float32Array([...vertices[0],...vertices[1]])
      const material = new THREE.LineBasicMaterial();
      material.linewidth = 5;

      material.color.setHex(color);
      const geometry = new THREE.BufferGeometry();
      geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
      const line = new THREE.Line( geometry,  material) ;
      threeObj.scene.add( line )
      return line
    },
    createComment (sphere) {
        const moonDiv = document.createElement( 'div' );
        const nap = document.createElement('div')
        nap.id = 'newApp'
        moonDiv.appendChild(nap)
        moonDiv.className = 'labelBox';
        const moonLabel = new CSS2DObject( moonDiv );
        moonDiv.id = `labelBox-${sphere.uuid}`
        sphere.add( moonLabel );

        moonDiv.addEventListener('touchend', (event) => {
          if (moved) { return }
          this.newContent(event, moonDiv, sphere.uuid)
        }, false)
        moonDiv.addEventListener('click', (event) => {
          if (moved) { return }
          this.newContent(event, moonDiv, sphere.uuid)
        }, false)

        this.$nextTick(() => {
          let _this = this;
          this.pointLocation.lineMesh[3] = new Vue({
            render: h=> h(newApp),
            data(){
              return{
                pthis: _this,
                uuid: sphere.uuid
              }
            }
          }).$mount(`#${moonDiv.id} #newApp`)
          this.render();
        })
        this.commentBox.newLine.flag = true
    },
    newContent (uuid) {
      // event, moonDiv, sphere.uuid
      if (!this.commentBox.newLine.form.id) {
        this.pointLocation.lineMesh.forEach(a => {
            // if (a.type === 'Mesh') {
            //     a.geometry.dispose();//删除几何体
            //     a.material.dispose();//删除材质
            // }
          threeObj.scene.remove(a)
          if (a.children && a.children.length) { a.remove(a.children[0]) }
        })
        this.render()
      }
      this.commentBox.comments.forEach(a => {
        if (a.lineMesh[1].uuid == uuid) {
          this.pointLocation.line = a.line
          this.pointLocation.lineMesh = a.lineMesh
          this.commentBox.newLine.form.id = a.id
          this.commentBox.newLine.flag = true
        }
      })
    },
    clearLine () {
      if (!this.commentBox.newLine.form.id) {
        this.pointLocation.lineMesh.forEach(a => {
            // if (a.type === 'Mesh') {
            //     a.geometry.dispose();//删除几何体
            //     a.material.dispose();//删除材质
            // }
          threeObj.scene.remove(a)
          if (a.children && a.children.length) { a.remove(a.children[0]) }
        })
        this.render()
      }
      this.pointLocation.line = []
      this.pointLocation.lineMesh = []
      if (this.commentBox.newLine.flag) {
        this.$refs.addLineForm.resetFields();
        this.commentBox.newLine.form.id = ''
        this.commentBox.newLine.flag = false
      }
    },
    createMeasureLong (sphere) {

      const mDiv = document.createElement( 'div' );
      mDiv.className = "lBox"
      mDiv.id = `lBox-${sphere.uuid}`
      const moonLabel = new CSS2DObject( mDiv );
      const linearray = sphere.geometry.attributes.position.array
      moonLabel.position.set((linearray[0]+linearray[3])/2, (linearray[1]+linearray[4])/2, (linearray[2]+linearray[5])/2)
      const long = (new THREE.Vector3( linearray[0], linearray[1], linearray[2] )).distanceTo(new THREE.Vector3( linearray[3], linearray[4], linearray[5] ))
      mDiv.innerText = `${long.toFixed(2)}mm`
      sphere.add( moonLabel );

        mDiv.addEventListener('touchend', (event) => {
          if (moved) { return }
            this.lBoxClear(sphere.uuid, moonLabel)
        }, false)
        mDiv.addEventListener('click', (event) => {
          if (moved) { return }
            this.lBoxClear(sphere.uuid, moonLabel)
        }, false)

    },
    lBoxClear (uuid, moonLabel) {
      for (let i = 0; i < this.handleBottomBtn.measureLongArr.length; i+=3) {
        if (uuid == this.handleBottomBtn.measureLongArr[i + 2].uuid) {
          threeObj.scene.remove(moonLabel)
          threeObj.scene.remove(this.handleBottomBtn.measureLongArr[i])
          threeObj.scene.remove(this.handleBottomBtn.measureLongArr[i + 1])
          threeObj.scene.remove(this.handleBottomBtn.measureLongArr[i + 2])
          document.querySelector('.labelRendererBox').removeChild(moonLabel.element)
        }
      }
      this.render();
    },
    createMeasureAngle (sphere, list) {
      let v1 = (new THREE.Vector3(...list[0])).sub(new THREE.Vector3(...list[1]))
      let v2 = (new THREE.Vector3(...list[2])).sub(new THREE.Vector3(...list[1]))
      const angle = v1.angleTo(v2)/Math.PI*180

      const mDiv = document.createElement( 'div' );
      mDiv.className = "aBox"
      mDiv.id = `aBox-${sphere.uuid}`
      const moonLabel = new CSS2DObject( mDiv );
      mDiv.innerText = `${angle.toFixed(2)}°`
      sphere.add( moonLabel );

        mDiv.addEventListener('touchend', (event) => {
          if (moved) { return }
            this.aBoxClear(sphere.uuid, moonLabel)
        }, false)
        mDiv.addEventListener('click', (event) => {
          if (moved) { return }
            this.aBoxClear(sphere.uuid, moonLabel)
        }, false)
    },
    aBoxClear (uuid, moonLabel) {
      for (let i = 0; i < this.handleBottomBtn.measureAngleArr.length; i+=5) {
        if (uuid == this.handleBottomBtn.measureAngleArr[i+1].uuid) {
          threeObj.scene.remove(moonLabel)
          threeObj.scene.remove(this.handleBottomBtn.measureAngleArr[i])
          threeObj.scene.remove(this.handleBottomBtn.measureAngleArr[i + 1])
          threeObj.scene.remove(this.handleBottomBtn.measureAngleArr[i + 2])
          threeObj.scene.remove(this.handleBottomBtn.measureAngleArr[i + 3])
          threeObj.scene.remove(this.handleBottomBtn.measureAngleArr[i + 4])
          document.querySelector('.labelRendererBox').removeChild(moonLabel.element)
        }
      }
      this.render();
    },
    onPointerUpAnnotation (event) {
      let intersect = null
      event.preventDefault();

      threeObj.mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 );


      // 点是否需要在模型上
      // console.log(this.pointLocation.line)
      if (this.pointLocation.overType[this.pointLocation.line.length]) {

        threeObj.raycaster.setFromCamera( threeObj.mouse, threeObj.camera );
        const intersects = threeObj.raycaster.intersectObjects( threeObj.modelsMeshs );
        if (intersects.length) {
          for (let b in intersects) {
            for (let a in threeObj.models) {
              if (!/meshs$/.test(a)) { continue }
              if (threeObj.models[a].indexOf(intersects[b].object) != -1 && threeObj.models[a.replace(/meshs$/,'')].visible) {
                intersect = intersects[b]
                break;
              } else {
              }
            }
            if (intersect) break;
          }
        } else {
          // this.$message.error('请点击模型!')
        }
        if (!intersect) { return }

        this.pointLocation.line.push([intersect.point.x,intersect.point.y,intersect.point.z])
        let sphere = this.createPoint(this.pointLocation.line[this.pointLocation.line.length - 1])
        this.pointLocation.lineMesh.push(sphere)

      } else {
        const z = new THREE.Vector3(...this.pointLocation.line[0]).project(threeObj.camera).z
        let vector = new THREE.Vector3(threeObj.mouse.x, threeObj.mouse.y, z).unproject(threeObj.camera);

        this.pointLocation.line.push([vector.x,vector.y,vector.z])
        this.pointLocation.lineMesh.push(this.createPoint(this.pointLocation.line[this.pointLocation.line.length - 1]))
      }
      // 标注
      // annotation: false,
      // 长度
      // measureLong: false,
      // 角度
      // measureAngle: false,
      if (this.pointLocation.line.length >= 2) {
        this.pointLocation.lineMesh.push(this.createLine([
          this.pointLocation.line[this.pointLocation.line.length-2],
          this.pointLocation.line[this.pointLocation.line.length-1]
        ]))
      }
      
      if (!(this.pointLocation.line.length % this.pointLocation.overType.length)) {
        if (this.handleBottomBtn.annotation) {
          this.createComment(this.pointLocation.lineMesh[1])
        }
        if (this.handleBottomBtn.measureLong ) {
          this.createMeasureLong(this.pointLocation.lineMesh[this.pointLocation.lineMesh.length - 1])
          this.handleBottomBtn.measureLongArr.push(...this.pointLocation.lineMesh)
          this.pointLocation.line = []
          this.pointLocation.lineMesh = []
        }
        if (this.handleBottomBtn.measureAngle ) {
          this.createMeasureAngle(this.pointLocation.lineMesh[this.pointLocation.lineMesh.length - 4], this.pointLocation.line)
          this.handleBottomBtn.measureAngleArr.push(...this.pointLocation.lineMesh)
          this.pointLocation.line = []
          this.pointLocation.lineMesh = []
        }
      }
        this.render();

    },
    onPointerUps (event) {
      // pointerup,touchend 重复点击bug
      
      let _new = new Date().getTime()
      if (onPointerUpsTime) {
        if (_new - onPointerUpsTime < 500) { return }
      }
      onPointerUpsTime = new Date().getTime()


      if (event.type == 'touchend') {
        event.clientX = event.changedTouches[0].clientX
        event.clientY = event.changedTouches[0].clientY
      }
      if (event.target.className != 'labelRendererBox') { return }
      if (moved) { return }
      if (this.handleBottomBtn.annotation) { this.onPointerUpAnnotation(event); return }
      if (this.handleBottomBtn.measureLong) { this.onPointerUpAnnotation(event); return }
      if (this.handleBottomBtn.measureAngle) { this.onPointerUpAnnotation(event); return }

      let upKey = ''
      event.preventDefault();
      threeObj.mouse.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1 );
      threeObj.raycaster.setFromCamera( threeObj.mouse, threeObj.camera );
      const intersects = threeObj.raycaster.intersectObjects( threeObj.modelsMeshs );
      if (!intersects.length) {
        upKey = ''
      } else {
        for (let b in intersects) {
          for (let a in threeObj.models) {
            if (!/meshs$/.test(a)) { continue }
            if (threeObj.models[a].indexOf(intersects[b].object) != -1 && threeObj.models[a.replace(/meshs$/,'')].visible) {
              upKey = a.replace(/meshs$/,'')
              break;
            } else {
              upKey = ''
            }
          }
          if (upKey) break;
        }
      }


      this.handleLeftBox.choseModels = upKey?[parseInt(upKey)]: []
      this.choseCurrentKey()
      this.render();
    },

      // //还原默认模型的状态
      reloadDepthWrite (){
          this.modelList.map(a => {
              threeObj.models[a.id].traverse( function ( child ) {
                  if (child.type == 'Mesh') {
                      child.renderOrder = 0
                  }
              })
          })
      },
      // reloadDepthWrite (){
      //     this.modelList.map(a => {
      //         threeObj.models[a.id].traverse( function ( child ) {
      //             if (child.type == 'Mesh') {
      //                 child.material.depthWrite = true
      //             }
      //         })
      //     })
      // },
      // //改变选中模型的状态
      // changeDepthWrite (){
      //     this.handleLeftBox.choseModels.forEach(i => {
      //         threeObj.models[i].traverse(( child ) => {
      //             if ( child.material ) {

      //                     child.material.depthWrite = false

      //             }
      //         });
      //     })
      // },
      // //清楚模型的内存占用
      // clearModelCache (){
      //     this.modelList.map(a => {
      //         threeObj.models[a.id].traverse( function ( child ) {
      //             if (child.type == 'Mesh') {
      //                 child.geometry.dispose();
      //                 child.material.dispose();
      //             }
      //         })
      //     })
      // },
    choseCurrentKey () {
      threeObj.centerModel.visible = false
      this.render()
      // threeObj.transformControl.detach()
      // threeObj.outlinePass.selectedObjects = this.handleLeftBox.choseModels.map(a => threeObj.models[a])
      // threeObj.models[this.handleLeftBox.choseModels[0]]
      this.getMInfo(this.modelList)
      this.reloadDepthWrite();
        //还原默认模型的状态
        // this.modelList.map(a => {
        //     threeObj.models[a.id].traverse( function ( child ) {
        //         if (child.type == 'Mesh') {
        //             child.material.depthWrite = true
        //         }
        //     })
        // })
      if (!this.handleLeftBox.choseModels.length) {
        this.handleLeftBox.isIndeterminate = false; return
      } else if (this.handleLeftBox.choseModels.length != this.modelList.length) {
        this.handleLeftBox.isIndeterminate = true
      }
      let [x,y,z,_x,_y,_z] = [null,null,null,null,null,null]
      let choseGroup = new THREE.Group()
      this.handleLeftBox.choseModels.forEach(a => {
        choseGroup.add(threeObj.models[a].clone())
        if (x === null) {
          x = threeObj.modelsClipPlanes[a]['0'].constant
          y = threeObj.modelsClipPlanes[a]['1'].constant
          z = threeObj.modelsClipPlanes[a]['2'].constant
          _x = threeObj.modelsClipPlanes[a]['3'].constant
          _y = threeObj.modelsClipPlanes[a]['4'].constant
          _z = threeObj.modelsClipPlanes[a]['5'].constant
        }
        if (threeObj.modelsClipPlanes[a]['0'].constant > x) { x = threeObj.modelsClipPlanes[a]['0'].constant }
        if (threeObj.modelsClipPlanes[a]['1'].constant > y) { y = threeObj.modelsClipPlanes[a]['1'].constant }
        if (threeObj.modelsClipPlanes[a]['2'].constant > z) { z = threeObj.modelsClipPlanes[a]['2'].constant }
        if (threeObj.modelsClipPlanes[a]['3'].constant > _x) { _x = threeObj.modelsClipPlanes[a]['3'].constant }
        if (threeObj.modelsClipPlanes[a]['4'].constant > _y) { _y = threeObj.modelsClipPlanes[a]['4'].constant }
        if (threeObj.modelsClipPlanes[a]['5'].constant > _z) { _z = threeObj.modelsClipPlanes[a]['5'].constant }
      })
      const box = new THREE.Box3().setFromObject(choseGroup)

      // this.handleBottomBox.sectionFrom.maxX = parseInt(box.max.x + 5)
      // this.handleBottomBox.sectionFrom.maxY = parseInt(box.max.y + 5)
      // this.handleBottomBox.sectionFrom.maxZ = parseInt(box.max.z + 5)
      // this.handleBottomBox.sectionFrom.minX = parseInt(box.min.x - 5)
      // this.handleBottomBox.sectionFrom.minY = parseInt(box.min.y - 5)
      // this.handleBottomBox.sectionFrom.minZ = parseInt(box.min.z - 5)

      // this.handleBottomBox.sectionFrom._maxX = -parseInt(box.min.x - 5)
      // this.handleBottomBox.sectionFrom._maxY = -parseInt(box.min.y - 5)
      // this.handleBottomBox.sectionFrom._maxZ = -parseInt(box.min.z - 5)
      // this.handleBottomBox.sectionFrom._minX = -parseInt(box.max.x + 5)
      // this.handleBottomBox.sectionFrom._minY = -parseInt(box.max.y + 5)
      // this.handleBottomBox.sectionFrom._minZ = -parseInt(box.max.z + 5)

      this.handleBottomBox.sectionFrom.xRange = [parseInt(box.min.x - 1), parseInt(box.max.x + 1)]
      this.handleBottomBox.sectionFrom.yRange = [parseInt(box.min.y - 1), parseInt(box.max.y + 1)]
      this.handleBottomBox.sectionFrom.zRange = [parseInt(box.min.z - 1), parseInt(box.max.z + 1)]
      this.handleBottomBox.sectionFrom.x = [-_x, x]
      this.handleBottomBox.sectionFrom.y = [-_y, y]
      this.handleBottomBox.sectionFrom.z = [-_z, z]
      // this.handleBottomBox.sectionFrom._x = _x
      // this.handleBottomBox.sectionFrom._y = _y
      // this.handleBottomBox.sectionFrom._z = _z

      threeObj.models[this.handleLeftBox.choseModels[0]].traverse(( child ) => {
          if (child.type == 'Mesh') {
            this.handleBottomBox.alphaFrom.opacity = child.material.opacity * 100
            this.handleBottomBox.colorFrom.color = `#${child.material.color.getHexString()}` || this.handleBottomBox.colorFrom.color
          }
      })
      let _m = threeObj.models[this.handleLeftBox.choseModels[this.handleLeftBox.choseModels.length - 1]]
      // threeObj.transformControl.attach( _m )


      let _mbox = new THREE.Box3().setFromObject(_m)
      const _mcenter = _mbox.getCenter( new THREE.Vector3() )

      threeObj.centerModel.position.set(_mcenter.x, _mcenter.y, _mcenter.z)
      threeObj.centerModel.visible = true
      this.render()
      // threeObj.transformControl.position.set(_mcenter.x, _mcenter.y, _mcenter.z)

      for (let a in this.handleBottomBox) {
        if (this.handleBottomBox[a].flag) {
          this.handleBottomBox[a].flag = false
          this.$nextTick(() => { this.handleBottomBox[a].flag = true })
        }
      }
    },
    getMaxScale(_size) {
      let {x,y,z} = _size
      if (!(x && y && z)) { return 0 }
      let max = 0
      if (x >= y && x >= z) { max = x }
      if (y >= x && y >= z) { max = y }
      if (z >= x && z >= y) { max = z }
      return 150/max
    },
    resetXYZ () {
      for (let a in threeObj.models) {
        if (/meshs$/.test(a)) { continue }
        const box = new THREE.Box3().setFromObject(threeObj.models[a])
        threeObj.modelsClipPlanes[a]['0'].constant = parseInt(box.max.x + 5)
        threeObj.modelsClipPlanes[a]['1'].constant = parseInt(box.max.y + 5)
        threeObj.modelsClipPlanes[a]['2'].constant = parseInt(box.max.z + 5)

        threeObj.modelsClipPlanes[a]['3'].constant = -parseInt(box.min.x - 5)
        threeObj.modelsClipPlanes[a]['4'].constant = -parseInt(box.min.y - 5)
        threeObj.modelsClipPlanes[a]['5'].constant = -parseInt(box.min.z - 5)
      }


      let box = new THREE.Box3().setFromObject(threeObj.group)
      const center = box.getCenter( new THREE.Vector3() )
      threeObj.controls.target.x += ( threeObj.controls.target.x + center.x );
      threeObj.controls.target.y += ( threeObj.controls.target.y + center.y );
      threeObj.controls.target.z += ( threeObj.controls.target.z + center.z );
      // const max = parseInt(Math.max(...Object.values(box.size())) * 2.5)
      // threeObj.camera.position.set(max, max, max)
      // let max  = parseInt(Math.max(...Object.values(box.size())))
      // let boxSize = box.size()
      let boxSize = box.getSize()

      threeObj.camera.position.set(threeObj.controls.target.x, -boxSize.z*2.4 + threeObj.controls.target.y, threeObj.controls.target.z )

      threeObj.camera.updateProjectionMatrix();
      threeObj.controls.update();
      this.handleLeftBox.choseModels = []

      this.render();
    },
    initModels (modeArr) {
      this.three.loading = true
      Promise.all((() => {
        return modeArr.map((a,index) => {
          return this.loadModel(a,index)
        })
      })()).then(resArr => {
        // this.$parent.$refs.ctView.showOne()
        this.three.loading = false
        resArr.forEach((a, b) => {
          let meshs = []
          threeObj.modelsClipPlanes[a.modelInfo.id] = [
            new THREE.Plane( new THREE.Vector3( - 1, 0, 0 ), 0 ),
            new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 0 ),
            new THREE.Plane( new THREE.Vector3( 0, 0, - 1 ), 0 ),
            new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 ),
            new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 0 ),
            new THREE.Plane( new THREE.Vector3( 0, 0, 1 ), 0 ),
          ]
          a.group.traverse( ( child ) => {
            // if (child.type == 'BufferGeometry') {
            //   console.log(child ,1111111)
            //   delete child.attributes.color
            // }
            if (child.type == 'Mesh') {
              let _color = ''
              if (child.geometry && child.geometry.attributes.color) {
                _color = new THREE.Color(child.geometry.attributes.color.array[0],
                        child.geometry.attributes.color.array[1],
                        child.geometry.attributes.color.array[2]).getHexString()
                if (child.geometry.attributes.color) child.geometry.attributes.color.array.fill(1)
              }
              // console.log(child)
              child.visible = a.modelInfo.show
              child.alphaTest = 0.1
              child.name = a.modelInfo.name
          
              // child.material.depthTest = false
              //  child.material.depthWrite = false
              child.material.transparent = true
              // child.material.clipShadows = true
              child.material.clippingPlanes = threeObj.modelsClipPlanes[a.modelInfo.id]
              child.material.clipIntersection = false
              child.material.lights = true
                child.material.vertexTangents = false
              if (_color) child.material.color.set(`#${_color}`)
              child.material.rcolor = child.material.color.clone()
              this.modelList[b].color = `#${child.material.rcolor.clone().getHexString()}`
              child.material.opacity = a.modelInfo.opacity
              child.material.side = THREE.DoubleSide
          
              meshs.push(child)
              threeObj.modelsMeshs.push(child)
            }
          } );
          a.group.renderOrder = a.modelInfo.id
          threeObj.models[a.modelInfo.id] = a.group
          threeObj.models[`${a.modelInfo.id}meshs`] = meshs
          
          // threeObj.modelsHelper[a.modelInfo.id] = new VertexNormalsHelper( a.group, 5 );
          // console.log(threeObj.modelsHelper[a.modelInfo.id], a.group)
          // let wireframe = new THREE.WireframeGeometry( meshs[1].geometry.clone() )
          // meshs.forEach((x,y) => {
          //   if (y === 0) { return }
          //   // wireframe.merge(x.geometry.clone())
          // })
          // let line = new THREE.LineSegments( wireframe );
          // line.material.color.set(`#FF0000`)
          // line.material.depthTest = false;
          // line.material.opacity = 0.25;
          // line.material.transparent = true;
          // line.position.x = 4;
          // threeObj.modelsHelper[a.modelInfo.id] = line;
          
          // threeObj.modelsHelper[a.modelInfo.id] = new THREE.BoxHelper( a.group , 0xff0000)
          // threeObj.modelsHelper[a.modelInfo.id].visible = false
          
          threeObj.group.add(a.group)
          // threeObj.scene.add( threeObj.modelsHelper[a.modelInfo.id]  )
        })
        if (this.$parent.$refs.ctView) {
          this.$parent.$refs.ctView.initct()
          this.$parent.$refs.ctView.busModel(threeObj.group.clone())
        }
        threeObj.scene.add( threeObj.group );
        //获取所有模型总体积
        this.getTotalVolume ()
        this.resetXYZ()
        this.saveModelColors()

      })
    },
    saveModelColors () {
      let canvas, ctx
      let lineNum = 4
      let cvsBorder = 40
      let _b = {w: 100, h: 60}
      canvas = document.createElement('canvas')
      canvas.id = 'outCanvas'
      document.body.appendChild(canvas)
      canvas.width = _b.w * lineNum + (cvsBorder - 10) * (lineNum - 1) + (cvsBorder * 2)
      canvas.height = Math.ceil(this.modelList.length / lineNum) * _b.h + (cvsBorder * 2) - (_b.h / 2)
      ctx = canvas.getContext('2d')

      let x, y
      let row = 0
      this.modelList.forEach((a, b) => {
        if (b % lineNum == 0) { x = 0; row++ }
        x = cvsBorder + b % lineNum * (_b.w + (cvsBorder - 10))
        y = cvsBorder + (row - 1) * _b.h
        creatRect(a.name.replace(/\.[^\.]+$/, ''), a.color, x, y)
      })

      let par = {
        id: this.$route.params.id,
        modelColorImage: canvas.toDataURL("image/png")
      }
      // 上传颜色
      uploadModelColorBase64(par).then(res => {
        // console.log(res)


      })


      function creatRect (name, color, x, y) {
        // console.log(name, color, x, y)
        ctx.save();
        ctx.fillStyle = color;
        ctx.strokeStyle = '#000';
        ctx.lineWidth = 1
        ctx.fillRect(x, y, _b.w, (_b.h / 2));
        ctx.strokeRect(x, y, _b.w, (_b.h / 2));
        ctx.restore();


        ctx.save();
        ctx.font = `12px "微软雅黑"`; 
        ctx.textBaseline="hanging";
        ctx.textAlign = 'center';
        ctx.fillStyle = '#000'
        ctx.fillText(name, x + (_b.w / 2), y + (_b.h / 2 + 5))

        ctx.restore();
      } 
    },
    render() {
        //threejs的webglrenderer提供了compile方法来编译场景，先执行这个方法后，再开始渲染，就不会卡顿
        // threeObj.renderer.compile(threeObj.scene, threeObj.camera );
      threeObj.renderer.render( threeObj.scene, threeObj.camera );
      // threeObj.composer.render();
      threeObj.labelRenderer.render( threeObj.scene, threeObj.camera );

    },
    onWindowResize() {

      threeObj.camera.aspect = window.innerWidth / window.innerHeight;
      threeObj.camera.updateProjectionMatrix();

      threeObj.renderer.setSize( window.innerWidth, window.innerHeight );
      threeObj.labelRenderer.setSize( window.innerWidth, window.innerHeight );


      // threeObj.composer.setSize( window.width, window.height );
      // threeObj.effectFXAA.uniforms[ 'resolution' ].value.set( 1 / window.innerWidth, 1 / window.innerHeight );

      this.render();

    },
    loadModel (modelInfo,index) {
      return new Promise((reslove, reject) => {
        threeObj.loder.ThreeMFLoader.load(modelInfo.url, (group) =>  {
            //test
            // let meshs = []
            // threeObj.modelsClipPlanes[modelInfo.id] = [
            //     new THREE.Plane( new THREE.Vector3( - 1, 0, 0 ), 0 ),
            //     new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 0 ),
            //     new THREE.Plane( new THREE.Vector3( 0, 0, - 1 ), 0 ),
            //     new THREE.Plane( new THREE.Vector3( 1, 0, 0 ), 0 ),
            //     new THREE.Plane( new THREE.Vector3( 0, 1, 0 ), 0 ),
            //     new THREE.Plane( new THREE.Vector3( 0, 0, 1 ), 0 ),
            // ]
            // group.traverse( ( child ) => {
            //     if (child.type == 'Mesh') {
            //         let _color = ''
            //         if (child.geometry && child.geometry.attributes.color) {
            //             _color = new THREE.Color(child.geometry.attributes.color.array[0],
            //                 child.geometry.attributes.color.array[1],
            //                 child.geometry.attributes.color.array[2]).getHexString()
            //             if (child.geometry.attributes.color) child.geometry.attributes.color.array.fill(1)
            //         }
            //         child.visible = modelInfo.show
            //         child.material.transparent = true
            //         // child.material.clipShadows = true

            //         // child.material.clippingPlanes = threeObj.modelsClipPlanes[modelInfo.id]
            //         child.material.clipIntersection = false
            //         //child.material.flatShading = false
            //          child.material.lights = true
            //         child.material.vertexTangents = false
            //         if (_color) child.material.color.set(`#${_color}`)
            //         child.material.rcolor = child.material.color.clone()
            //         this.modelList[index].color = `#${child.material.rcolor.clone().getHexString()}`
            //         child.material.opacity = modelInfo.opacity
            //         child.material.side = THREE.DoubleSide

            //         meshs.push(child)
            //         threeObj.modelsMeshs.push(child)
            //     }
            // } );
            // threeObj.models[modelInfo.id] = group
            // threeObj.models[`${modelInfo.id}meshs`] = meshs
            // threeObj.group.add(group)
            //test
          reslove({group, modelInfo})
        }, (xhr) => {
            console.error( xhr );
          this.$set(this.three.loadProgress, xhr.total, xhr.loaded)
        })
      })
    },
    clipPic () {
      return new Promise((resolve, reject) => {

        let labelBoxAll = document.querySelectorAll('.labelBox')
        let transforms = []
        labelBoxAll.forEach((a, b) => {
          transforms.push(a.style.transform)
           const _tf = a.style.transform.match(/(\d*\.?\d*)/g).filter(x => x)
           a.style.transform = ''
           a.style.top = `${-a.offsetHeight/2 + Number(_tf[3])}px`
           a.style.left = `${-a.offsetWidth/2 + Number(_tf[2])}px`
        })
        html2canvas(this.$refs.screen3d, {scale: window.devicePixelRatio}).then(canvas => {
          labelBoxAll.forEach((a, b) => {
            a.style.transform = transforms[b]
            a.style.top = `0`
            a.style.left = `0`
          })
          let dataURL = canvas.toDataURL("image/png");
          // console.log(dataURL, 111)
          resolve(dataURL)
        });

      })
      // this.$emit('upDate', 'modelScreenshot', 0, this.$refs.screen3d.querySelector('canvas').toDataURL())
    },
    clearUnfinished () {
      this.pointLocation.line = []
      this.pointLocation.lineMesh.forEach(a => {
          // if (a.type === 'Mesh') {
          //     a.geometry.dispose();//删除几何体
          //     a.material.dispose();//删除材质
          // }
        threeObj.scene.remove(a)
      })
      this.pointLocation.lineMesh = []
      this.render();
    },
    sixView (type) {
      this.handleBottomBtn.activeSixViewIndex = type;
      let box = new THREE.Box3().setFromObject(threeObj.group)
      const center = box.getCenter( new THREE.Vector3() )
      let boxSize = box.getSize()
      // let boxSize2 = box.size() //新版size()方法已被getSize()代替
      console.log(box)
      console.log(boxSize)   
      console.log(center)
      // let max  = parseInt(Math.max(...Object.values(box.size())))
      let n = 2.4
      switch (type) {
        case 1:
        // 前
        threeObj.camera.position.set(center.x, -boxSize.z*n + center.y, center.z )
        break;
        case 2:
        // 后
        threeObj.camera.position.set(center.x, boxSize.z*n + center.y, center.z )
        break;
        case 3:
        // 左
        threeObj.camera.position.set(boxSize.z*n + center.x, center.y, center.z )
        break;
        case 4:
        // 右
        threeObj.camera.position.set(-boxSize.z*n + center.x, center.y, center.z )
        break;
        case 5:
        // 上
        threeObj.camera.position.set(center.x, center.y, boxSize.y*n + center.z )
        break;
        case 6:
        // 下
        threeObj.camera.position.set(center.x, center.y, -boxSize.y*n + center.z )
        break;
      }
      threeObj.controls.update();
    },
    toolFn (key) {
      for (let a in this.handleBottomBtn) {
        if (typeof this.handleBottomBtn[a] == 'boolean') {
          if (key == a) {
            this.handleBottomBtn[a] = !this.handleBottomBtn[a]
          } else {
            this.handleBottomBtn[a] = false
          }
        }
      }
      this.clearUnfinished()
      // if (!this.handleBottomBtn[key]) {
      // }
      switch(key) {
        case 'annotation':
          this.pointLocation.overType = [true, false]; 
          break;
        case 'measureLong':
          this.pointLocation.overType = [true, true]; 
          break;
        case 'measureAngle':
          this.pointLocation.overType = [true, true, true]; 
          break;
        case 'hiddenMeasure':
          break;
        default:
          // 默认
      }
      this.handleBottomBtn.measureAngleArr.forEach(a => {
        a.visible = !this.handleBottomBtn.hiddenMeasure
      })
      this.handleBottomBtn.measureLongArr.forEach(a => {
        a.visible = !this.handleBottomBtn.hiddenMeasure
      })
      this.commentBox.comments.forEach(a => {
        a.lineMesh.forEach(c => {
          if (['Mesh', 'Line'].includes(c.type)) {
            c.visible = !this.handleBottomBtn.hiddenMeasure
          }
        })
      })
      document.querySelector('.labelRendererBox').style.opacity = !this.handleBottomBtn.hiddenMeasure ? '1' : '0'

    },
    onBlur () {
      window.scrollTo(0, 0)
    },
    wsinit () {
      //this.ws = new WebSocket('ws://192.168.103.149:8728/temr/filterSkip/webSocket');
      this.ws = new WebSocket(window.SITE_CONFIG['ws']);
      this.ws.onopen = this.wsonopen;
      this.ws.onmessage = this.wsonmessage;
      this.ws.onerror = this.wsonerror;
      this.ws.onclose = this.wsclose;
    },
    wsonopen () {
      this.wssend({type: 0,createBy:this.userInfo.id,medicalRecordId:this.$route.params.id,});
    },
    wssend (msg) {
      this.ws.send(JSON.stringify(msg))
    },
    wsonmessage (msg) {
      let msgInfo = JSON.parse(msg.data)
      if(msgInfo.data.type=== 1){ //接收消息的返回值
        for(let i=0;i<this.commentBox.comments.length;i++){
          if(msgInfo.data.modelLabelId == this.commentBox.comments[i].id){
              // this.commentBox.comments[i].contents.push()
              this.commentBox.comments[i].lineMesh[3].$children[0].addList({
                user: msgInfo.data.name,
                content: msgInfo.data.message,
                modelLabelId:msgInfo.data.modelLabelId
              })
            //
          }
        }
        this.clearLine(true)
      }else if(msgInfo.data.type === 2){  //发送消息的返回值
        if(msgInfo.message ==='success'){
          console.log('消息发送成功')
        }else{
          console.log('消息发送失败')
        }
      }else if(msgInfo.data.type === 0){
        if(msgInfo.message ==='success'){
          console.log('登录订阅成功')
        }else{
          console.log('登录订阅失败')
        }
      }else if(msgInfo.data.type=== 3){ //删除label框
        console.log(msgInfo)
        this.commentBox.comments = this.commentBox.comments.filter(a => {
          if (a.id == msgInfo.data.modelLabelId) {
            a.lineMesh[1].remove(a.lineMesh[1].children[0])
            threeObj.scene.remove(a.lineMesh[0])
            threeObj.scene.remove(a.lineMesh[1])
            threeObj.scene.remove(a.lineMesh[2])

          } else {
            return a
          }
        })
        //this.queryLabelContents()
        // window.location.reload()
      }
    },
    wsonerror (e) {
      this.wsinit()
    },
    wsclose (e) {
      console.log('close', e)
    },
  },
  destroyed () {
    this.ws.close();
  },
  beforeDestroy() {
      //内存中销毁删除
      try {
          threeObj.scene.clear()
          threeObj.renderer.dispose()
      } catch (e) {
          console.log(e)
      }
  },
}
</script>
<style scoped lang="less">
@nav_height: 50px;
.omit {
  white-space: nowrap;
  overflow:  hidden;
  text-overflow:  ellipsis;
}

.modelView {
  height: 100%;
  overflow: hidden;
  .vsBox {
    position: fixed;
    bottom: 100px;
    left: 0;
    padding-left: 10px;
    z-index: 1;
    p {
      font-size: 12PX;
      margin: 4PX 0;
    }
  }
}
.addLineForm .addLineeFormBtns {
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  .el-button {
    color: #333;
    width: 135px;
    border: 1px solid #ffb700;
    background-color: #fff;
    &.el-button--primary {
      color: #fff;
    }
  }
}
#inset3d {
  width: 100PX;
  height: 100PX;
  background-color: transparent;
  border: none;
  margin: 0;
  padding: 0px;
  position: absolute;
  right: 0px;
  bottom: @nav_height;
  z-index: 2;
}
</style>

<style lang="less">
.labelBox {
  width: 120px;
  min-height: 35px;
  // min-height: 60px;
  // max-height: 80px;
  background-color: #FFFFF0;
  border: 1px solid #ffb700;
  overflow-y: auto;
  font-size: 12px;
}
#_indicateLabel {
  background-color: rgba(105, 105, 105, 0.8);
  border: 1PX solid #696969;
  width: 6PX;
  height: 6PX;
  border-radius: 50%;
  z-index: 999999 !important;
}
.lBox,.aBox {
  font-size: 10px;
  color: #409EFF;
  background-color: #fff;
  border-radius: 4px;
  padding: 2px 6px;
}
#outCanvas {
  position: fixed;
  top: -10000px;
  left: -10000px;
  // z-index: 999;
}
</style>